package Model;

import java.nio.ByteBuffer;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.HashMap;
import java.util.Map;

public class DB 
{
	private final String DB_DRIVER = "org.apache.derby.jdbc.EmbeddedDriver";
	private final String DB_CONNECTION = "jdbc:derby:AnonPoP;create=true";
	
	// TODO: Move queries to file?
	private final String CREATE_DB_QUERY = "CREATE TABLE Messages\n"+
            "(Message_Token varchar(300) NOT NULL, Message varchar(300) not null, Index int not null)";
	
	private final String SELECT_ALL_MESSAGES = "select * from Messages order by Message_Token,index";
	
	private final String INSERT_NEW_MESSAGE = "insert into Messages values ('%s','%s',%d)";
	
	private final String CLEAR_DATABASE = "truncate table Messages";

	public DB()
	{		
        createDb();
	}
	
	private Connection getConnection() throws ClassNotFoundException, SQLException
	{
		// TODO: I think the following line can be at the constructor
		Class.forName(DB_DRIVER);
        return DriverManager.getConnection(DB_CONNECTION);
	}
	
	private void executeQuery(String query)
	{
		Connection connection = null;
		try 
        {
            connection = getConnection();

            PreparedStatement pstmt = connection.prepareStatement(query);
            pstmt.executeUpdate();           
        } 
        catch( Exception e ) 
        { 

        }
		finally
		{
			try 
			{
				connection.close();
			} 
			catch (SQLException e) {}
		}
	}
	
	private HashMap<ByteBuffer, Messages> resultSetQuery(String query)
	{
		Connection connection = null;
		try 
        {
            connection = getConnection();

            PreparedStatement pstmt = connection.prepareStatement(query);
            ResultSet rs = pstmt.executeQuery();
            
            HashMap<ByteBuffer, Messages> map = new HashMap<ByteBuffer, Messages>(); 
            
            if (rs != null && rs.next())
			{				
				String lastToken = rs.getString("Message_Token");
				Messages msgs = new Messages();
				
				do
				{
		            String token = rs.getString("Message_Token");
		            String message = rs.getString("Message");
		            int index = rs.getInt("Index");
		            
		            if (!lastToken.equals(token))
		            {
		            	map.put(ByteBuffer.wrap(lastToken.getBytes()), msgs);
		            	lastToken = token;
		            	msgs = new Messages();
		            }
		            
		            msgs.append(message.getBytes(), index);
		        }
				while (rs.next());	
				
				map.put(ByteBuffer.wrap(lastToken.getBytes()), msgs);	            
			}
            
            return map;
        } 
        catch( Exception e ) 
        { 

        }
		finally
		{
			try 
			{
				connection.close();
			} 
			catch (SQLException e) {}
		}
		return null;
	}
	
	public void createDb()
	{
		executeQuery(CREATE_DB_QUERY);		
	}
	
	public Map<ByteBuffer, Messages> load()
	{		
		return resultSetQuery(SELECT_ALL_MESSAGES);
	}

	public void remove(String token, int index) 
	{
		
	}

	public void append(byte[] token, byte[] msg, int index) 
	{
		executeQuery(String.format(INSERT_NEW_MESSAGE, token,msg,index));
	}
	
	public void clear() 
	{
		executeQuery(CLEAR_DATABASE);
	}
}
